package com.lanlian.cayman.socket;

import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.lanlian.commonlib.common.SystemConfig;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;

/**
 * Created by ygh on 2018/5/9.
 * 该类用于发送socket短链接
 */

public class MySocketManager {

   SocketCall sc;
    /**
     * 主 变量
     */

    // 主线程Handler
    // 用于将从服务器获取的消息显示出来
    private Handler handler;

    /**
     * 接收服务器消息 变量
     */
    // 输入流对象
    InputStream is;


    // 输入流读取器对象
    InputStreamReader isr ;
    BufferedReader br ;

    // 接收服务器发送过来的消息
    String response;
    Object send;

    /**
     * 发送消息到服务器 变量
     */
    // 输出流对象
    OutputStream outputStream;



    Socket socket;
    private Activity act;
    private String ip=SystemConfig.getSocketIp();

    private int count = 0;
    private boolean isCongLian=false;
    public void setCongLian(boolean isCongLian)
    {
        this.isCongLian=isCongLian;
    }

   public MySocketManager()
   {
       handler=new Handler()
       {
           @Override
           public void handleMessage(Message msg) {
              if(msg.what==1)
              {
                  sc.connect((Boolean) msg.obj);
              }
              else if(msg.what==2)
              {
                   sc.message((byte[])msg.obj);
              }
              else if(msg.what==3)
              {
                    sc.close();
              }
              else if(msg.what==4)
              {
                   sc.error((Exception) msg.obj);
              }


           }
       };
   }
   public void setIp(String ip)
   {
       this.ip=ip;
   }
    public void sendData(byte[]  data,SocketCall sc)
    {  String s1="";
//        for(int i=0;i<data.length;i++)
//        {
//            s1=s1+data[i]+",";
//        }
//        Log.e("data",s1);
        send=data;
        this.sc=sc;
        sc.init();
        new getThread().start();
        //new sendThread().start();
    }
    public void sendData(String  s1,SocketCall sc)
   {
       send=s1;
       this.sc=sc;
       sc.init();
      new getThread().start();
      //new sendThread().start();
   }

    public  void close()
    {
        try {
            // 断开 客户端发送到服务器 的连接，即关闭输出流对象OutputStream
            if(socket!=null) {
                socket.close();
                if(outputStream!=null) {
                    outputStream.close();
                }
                if(is!=null) {
                    is.close();
                }
            }

            // 断开 服务器发送到客户端 的连接，即关闭输入流读取器对象BufferedReader
           // br.close();

            // 最终关闭整个Socket连接

            Message msg3=new Message();
            msg3.what=3;

            handler.sendMessage(msg3);
            // 判断客户端和服务器是否已经断开连接
            //System.out.println(socket.isConnected());

        } catch (IOException e) {
            e.printStackTrace();
            Message msg4=new Message();
            msg4.what=4;
            msg4.obj=e;
            handler.sendMessage(msg4);
        }


    }


    class  sendThread  extends  Thread
    {
        @Override
        public void run() {

            try {
                // 步骤1：从Socket 获得输出流对象OutputStream
                // 该对象作用：发送数据
                outputStream = socket.getOutputStream();

                // 步骤2：写入需要发送的数据到输出流对象中
                outputStream.write((send+"\n").getBytes("utf-8"));
                // 特别注意：数据的结尾加上换行符才可让服务器端的readline()停止阻塞

                // 步骤3：发送数据到服务端
                outputStream.flush();

            } catch (Exception e) {
                e.printStackTrace();
                Message msg4=new Message();
                msg4.what=4;
                msg4.obj=e;
                handler.sendMessage(msg4);
            }

        }


    }


    class  getThread  extends  Thread
    {
        @Override
        public void run() {

            try{
                    // 创建Socket对象 & 指定服务端的IP 及 端口号
                    //socket = new Socket(ip, SystemConfig.getSocketPort());

                    socket = new Socket();
                    socket.connect(new InetSocketAddress(ip,SystemConfig.getSocketPort()),8000);
                    socket.setSoTimeout(8000);
                    socket.setTcpNoDelay(true);


                    // 判断客户端和服务器是否连接成功
                    // System.out.println(socket.isConnected());
                    // sc.connect(socket.isConnected());
                    Message msg = new Message();
                    msg.what = 1;
                    msg.obj = socket.isConnected();
                    handler.sendMessage(msg);


                    // 步骤1：从Socket 获得输出流对象OutputStream
                    // 该对象作用：发送数据
                    outputStream = socket.getOutputStream();

                    // 步骤2：写入需要发送的数据到输出流对象中
                    if (send instanceof String) {
                        outputStream.write((send + "\n").getBytes("utf-8"));
                    } else if (send instanceof byte[]) {
                        outputStream.write((byte[]) send);
                    }

                    // 特别注意：数据的结尾加上换行符才可让服务器端的readline()停止阻塞

                    // 步骤3：发送数据到服务端
                    outputStream.flush();
                    //socket.shutdownOutput();

//                    sleep(500);
                    // 步骤1：创建输入流对象InputStream
                    is = socket.getInputStream();


//                     getAvailable(is);


                    // 步骤2：创建输入流读取器对象 并传入输入流对象
                    // 该对象作用：获取服务器返回的数据
                    // isr = new InputStreamReader(is);
                    // br = new BufferedReader(isr);
                    //sleep(7000);
                    byte[] bytes = new byte[1024];
                    ArrayList<byte[]> list = new ArrayList<>();
                    ArrayList<Integer> list_size = new ArrayList<>();

                    int total = 0;
                    int len=0;

                    while (len!= -1)

                    {

                        len = is.read(bytes, 0, 1024);
                        if(len!=-1)
                        {
                            total = len + total;
                            list.add(bytes);
                            list_size.add(len);
                            bytes = new byte[1024];
                            if(len==1024)
                            {
                               // getAvailable(is);
                            }
                           // sleep(10);
                           // is.available();
                        }

                        //注意指定编码格式，发送方和接收方一定要统一，建议使用UTF-8
                        //sb.append(new String(bytes, 0, len,"UTF-8"));
                        //String s1="";
//                    for(int i=0;i<21;i++)
//                    {
//                        s1=s1+bytes[i]+" ";
//                    }

                    }


                    Log.e("total", total + "");


                    byte[] bytes2 = new byte[total];
                    int start = 0;
                    for (int i = 0; i < list.size(); i++) {
                        System.arraycopy(list.get(i), 0, bytes2, start, list_size.get(i));
                        start = start + list_size.get(i);
                    }


                    Message msg2 = new Message();
                    msg2.what = 2;
                    msg2.obj = bytes2;
                    handler.sendMessage(msg2);
                    if(isCongLian) {
                        count = 0;
                    }
                    close();


                // 步骤4:通知主线程,将接收的消息显示到界面
//                Message msg = new Message();
//                msg.what = 1;
//                msg.obj=s1;
//                handler.sendMessage(msg);



            } catch (Exception e) {
                e.printStackTrace();
              if(isCongLian) {
                  count++;
                  if (count < 2) {
                      run();
                  } else {
                      Message msg4 = new Message();
                      msg4.what = 4;
                      msg4.obj = e;
                      handler.sendMessage(msg4);
                      count = 0;
                      close();
                  }
              }
              else
              {
                  Message msg4 = new Message();
                  msg4.what = 4;
                  msg4.obj = e;
                  handler.sendMessage(msg4);
                  count = 0;
                  close();
              }


            }

        }


    }

    private int  getAvailable(InputStream is) throws IOException
    {
        int count = 0;
        long time1 = new Date().getTime();
        long time2 = 0;
        int total=0;
        while (count == 0) {
            count = is.available();


            time2 = new Date().getTime();
            if ((time2 - time1) > 5000) {
                break;
            }
        }
        return count;
    }
}
